Skip to content

Conversation

jkawan
Copy link
Contributor

@jkawan jkawan commented Aug 17, 2025

  1. Added changes to not return error while closing the connection for chainsync, block-fetch and tx-submission protocol- made changes in client,server and respective protocol files.
  2. Added unit tests to test the change.

Closes #1112

@jkawan jkawan requested a review from a team as a code owner August 17, 2025 01:43
@jkawan
Copy link
Contributor Author

jkawan commented Aug 17, 2025

  1. Added changes to not return error while closing the connection for chainsync, block-fetch and tx-submission protocol- made changes in client,server and respective protocol files.
  2. Added unit tests to test the change.

Closes #1112

c.stateMutex.Lock()
defer c.stateMutex.Unlock()
c.currentState = newState
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The protocol.Protocol base type already tracks the current state. It should be possible to add IsDone() there in a generic way by checking that the current state matches the initial state and/or the current state having AgencyNone.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

updated, could you please review when you get a chance ?

return err
}
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These checks need to be done at the top level, in Connection. We have an error handler for muxer errors there, and we can check the state of all active protocols from there.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

made the cahange, could you please review?

errStr := err.Error()
return strings.Contains(errStr, "connection reset") ||
strings.Contains(errStr, "broken pipe")
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should check for error types rather than substring matches of the Error() output. Do we actually get any "connection closed" error that isn't io.EOF?

connection.go Outdated
// checkProtocols checks if the protocols are explicitly stopped by the client- treat as normal connection closure
func (c *Connection) checkProtocols() bool {
// Check chain-sync protocol
if c.chainSync != nil && (!c.chainSync.Client.IsDone() || !c.chainSync.Server.IsDone()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Client or .Server can be nil, so we need nil checks against both

connection.go Outdated
}

// Check block-fetch protocol
if c.blockFetch != nil && (!c.blockFetch.Client.IsDone() || !c.blockFetch.Server.IsDone()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Client or .Server can be nil, so we need nil checks against both

connection.go Outdated
}

// Check tx-submission protocol
if c.txSubmission != nil && (!c.txSubmission.Client.IsDone() || !c.txSubmission.Server.IsDone()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.Client or .Server can be nil, so we need nil checks against both

// Check tx-submission protocol
if c.txSubmission != nil && (!c.txSubmission.Client.IsDone() || !c.txSubmission.Server.IsDone()) {
return false
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's also add LocalStateQuery, LocalTxMonitor, and LocalTxSubmission to this. It should be safe to do the NtN and NtC protocols all together with the nil checks.

case MessageTypeBatchDone:
err = c.handleBatchDone()
case MessageTypeClientDone:
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't belong here. The client will never receive the ClientDone message, only the server.

case MessageTypeIntersectNotFound:
err = c.handleIntersectNotFound(msg)
case MessageTypeDone:
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't belong here. The client will never receive this message, only the server

currentState := p.CurrentState()
if entry, exists := p.config.StateMap[currentState]; exists {
return entry.Agency == AgencyNone
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should also return true if the current state is the same as the configured initial protocol state.

case MessageTypeRequestTxs:
err = c.handleRequestTxs(msg)
case MessageTypeDone:
return nil
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't needed. The client will never receive this message, only the server

stateRespChan: stateChan,
}
return <-stateChan
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's probably a cleaner way to do this. Instead, let's make currentState defined at the top of stateLoop() a field in the Protocol type, and then we can access it more directly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Don't return an error on connection close when all protocols are shut down
2 participants